package com.binarysoft.service.common.snmp;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

import common.framework.dsb.AbstractServiceBean;
import common.framework.dsb.ServiceException;
import common.framework.dsb.annotation.DSBService;
import common.framework.dsb.service.ServiceContext;

/**
 * @author Yuan Shou Zheng
 * 
 */
@DSBService(name = "DSB/SnmpService")
public class SnmpServiceBean extends AbstractServiceBean implements SnmpService {
	private int pool_size = 5;

	public static int snmp_retry_count = 3;
	public static int snmp_timeout = 5000;
	private int snmp_group_size = 5;

	private boolean isClosed = false;
	private BlockingQueue<SnmpResouce> resourcePool = null;

	@Override
	public void start(ServiceContext serviceContext) throws Exception {
		super.start(serviceContext);
		serviceContext.loadConfigProperties("SnmpService.properties");
		pool_size = Integer.parseInt(serviceContext.getProperty("snmp_pool_size"));
		snmp_retry_count = Integer.parseInt(serviceContext.getProperty("snmp_retry_count"));
		snmp_timeout = Integer.parseInt(serviceContext.getProperty("snmp_timeout")) * 1000;
		snmp_group_size = Integer.parseInt(serviceContext.getProperty("snmp_group_size"));
		resourcePool = new ArrayBlockingQueue<SnmpResouce>(pool_size);
		for (int i = 0; i < pool_size; i++) {
			SnmpResouce snmpResouce = new SnmpResouceImpl();
			snmpResouce.open();
			resourcePool.add(snmpResouce);
		}
	}

	public SnmpResult snmpGet(Collection<SnmpObject> objectList, SnmpTarget target) throws Exception {
		SnmpTool.preprocess(objectList, target);
		// make result
		SnmpResult snmpResult = null;
		// take SNNP resource
		SnmpResouce snmpResouce = resourcePool.take();
		try {
			snmpResult = SnmpTool.collect(target, snmpResouce.getSnmp(), objectList, snmp_group_size);
		} finally {
			// return SNMP resource
			resourcePool.add(snmpResouce);
		}
		return snmpResult;
	}

	public SnmpResult snmpGet(SnmpObject snmpObject, SnmpTarget target) throws Exception {
		Set<SnmpObject> objects = new HashSet<SnmpObject>();
		objects.add(snmpObject);
		return snmpGet(objects, target);
	}

	public void close() throws ServiceException {
		for (SnmpResouce snmpResouce : resourcePool) {
			snmpResouce.close();
		}
		isClosed = true;
	}

	public void refresh() throws Exception {
	}

	@Override
	public int getPoolSize() {
		return resourcePool.size();
	}
}